/*
 * Copyright 2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.seppiko.chart.controllers;

import com.fasterxml.jackson.databind.JsonNode;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import org.seppiko.chart.models.ControllerEntity;
import org.seppiko.chart.models.MessageEntity;
import org.seppiko.chart.services.DecodeService;
import org.seppiko.chart.utils.HttpClientUtils;
import org.seppiko.chart.utils.JsonUtil;
import org.seppiko.chart.utils.ResponseUtil;
import org.seppiko.chart.utils.logging.LoggingManager;
import org.seppiko.commons.utils.Base64Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Leonard Woo
 */
@RestController
public class DecodeController {

  private static LoggingManager Logger = LoggingManager.getInstance().getLogger("DecodeController");

  @Autowired
  private DecodeService service;

  @GetMapping(value = "/decode")
  public ResponseEntity<byte[]> decodeGetContentHandleExecution() {
    ControllerEntity resp = new ControllerEntity();
    resp.setStatus(405);
    resp.setMediaType(MediaType.APPLICATION_JSON);
    resp.setData( JsonUtil.toJson(
        new MessageEntity(405, "Method Not Allowed.Only POST") ).getBytes() );
    return ResponseUtil.sendResponse( resp );
  }

  @PostMapping(value = "/decode")
  public ResponseEntity<byte[]> decodePostContentHandleExecution(@RequestBody String requestStr) {

    JsonNode root = JsonUtil.fromJsonObject(requestStr);
    String type = root.get("type").asText();
    String data = root.get("data").asText();

    ControllerEntity resp = new ControllerEntity();
    InputStream is = null;

    //iVBO
    if(type.equalsIgnoreCase("base64")) {
      is = new ByteArrayInputStream(Base64Util.decode(data));
    }

    //
    if(type.equalsIgnoreCase("uri")) {
      try {
        is = new BufferedInputStream(new URL(data).openStream());
      } catch (IOException ex) {
        Logger.warn("Image didn't exist", ex);
        is = null;
      }
    }

    // http://localhost/qr.png
    if(type.equalsIgnoreCase("url")) {
      byte[] body = HttpClientUtils.downloadGet(data);
      if (body != null) {
        is = new ByteArrayInputStream( body );
      } else {
        resp.setStatus(404);
        resp.setMediaType(MediaType.APPLICATION_JSON);
        resp.setData( JsonUtil.toJson(
            new MessageEntity(404, "URL content acquisition failed.") ).getBytes() );
        return ResponseUtil.sendResponse( resp );
      }
    }

    if (is == null) {
      resp.setStatus(404);
      resp.setMediaType(MediaType.APPLICATION_JSON);
      resp.setData( JsonUtil.toJson(
          new MessageEntity(404, "barcode not found.") ).getBytes() );
      return ResponseUtil.sendResponse( resp );
    }

    resp = service.decodeCHX( is );

    return ResponseUtil.sendResponse( resp );
  }
}
